package com.bclz.al.dynamic

import java.util


trait List[T] {

  /**
    * 大小
    * @return
    */
  def size(): Int = ???

  /**
    * 是否为空
    * @return
    */
  def isEmpty(): Boolean = ???

  /**
    * 添加
    * @param ele
    */
  def add(ele: T): Unit = ???

  def add(ele: T, index: Int): Unit = ???

  def set(ele: T, index: Int): T = ???

  def delete(index: Int): T = ???

  def get(index: Int): T = ???

  def clear(): Unit = ???
}


class ArrayList[T](capacity: Int) extends List[T] {

  //Error:(20, 28) cannot find class tag for element type T
  //  private var arr:Array[T]=new Array[T](capacity)
  // so use AnyRef
  private var arr: Array[AnyRef] = new Array[AnyRef](capacity)
  private var size0: Int = 0

  override def isEmpty(): Boolean = size0 == 0

  override def size(): Int = size0

  override def add(ele: T): Unit = {
    ensureCapacity(size0)
    arr(size0) = ele.asInstanceOf[AnyRef]
    size0 += 1
  }

  override def delete(index: Int): T = {
    rangeCheck(index)
    val oldEle = arr(index)
    val len = size0 - 1 - index
    System.arraycopy(arr, index + 1, arr, index, len)
    arr(size0) = null
    size0 -= 1
    oldEle.asInstanceOf[T]
  }

  override def get(index: Int): T = {
    rangeCheck(index)
    arr(index).asInstanceOf[T]
  }


  override def set(ele: T, index: Int): T = {
    rangeCheck(index)
    val oldEle = arr(index)
    arr(index) = ele.asInstanceOf[AnyRef]
    oldEle.asInstanceOf[T]
  }

  def ensureCapacity(index: Int): Unit = {
    if (index < arr.length) {
      return
    }
    val newCapacity = arr.length + (arr.length >> 2)
    this.arr = util.Arrays.copyOf(arr, newCapacity)
  }

  def rangeCheck(index: Int): Unit = {
    if (index < 0 || index >= size0) {
      throw new IndexOutOfBoundsException("index out of bound !!!")
    }
  }

  def rangeCheckForAdd(index: Int): Unit = {
    if (index < 0 || index > size0) {
      throw new IndexOutOfBoundsException("index out of bound !!!")
    }
  }

  override def toString: String = s"(${arr.toList})"

  override def add(ele: T, index: Int): Unit = {

    rangeCheckForAdd(index)
    ensureCapacity(size0 + 1)
    for (i <- (size0 - 1 to index by -1)) {
      this.arr(i + 1) = this.arr(i)
    }
    this.arr(index) = ele.asInstanceOf[AnyRef]

  }

  override def clear(): Unit = {
//    arr=null
    //不推荐这种方式对内存GC，会导致频繁分配空间

    for (i <- (0 until size0)) {
      arr(i) = null
    }
    size0 = 0
  }

}

object ArrayList {
  private val DEFAULT_LENGTH = 2 + (2 << 3)

  def apply[T](capacity: Int = DEFAULT_LENGTH): ArrayList[T] = new ArrayList[T](capacity)

  def main(args: Array[String]): Unit = {
    val list = ArrayList[Int](8)
    for (i <- (100 to 60 by -1)) {
      list.add(i)
    }
    list.add(9999, 3)
    println(list.size())
    println(list)
  }

}



